﻿
Array.prototype.Sum = function (property) {
    var items = this;
    var total = 0;
    var isFunction = typeof (property) == "function";
    for (var i = 0; i < items.length; i++) {
        if (isFunction) {
            total += property(items[i]);
        }
        else {
            var value = items[i][property];
            if (value != undefined && value != null) {
                total += value * 1;
            }
        }
    }
    return total;
};

Array.prototype.Where = function (predicateFunction) {
    var results = new Array();
    var items = this;
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (predicateFunction(item)) {
            results.push(item);
        }
    }
    return results;
};

Array.prototype.OrderBy = function (property, compare) {
    var items = this;
    for (var i = 0; i < items.length-1; i++) {
        for (var j =0; j < items.length - 1-i; j++) {
            if (IsFirstGreaterThanSecond(items[j], items[j + 1])) {
                var temp = items[j + 1];
                items[j + 1] = items[j];
                items[j] = temp;
            }
        }
    }
    function IsFirstGreaterThanSecond(first, second) {
        if (compare != undefined) {
            return compare(first, second);
        }
        else if (property == undefined || property == null) {
            return first > second;
        }
        else {
            return first[property] > second[property];
        }
    }

    return items;
};

Array.prototype.OrderByDescending = function (property, compare) {
    var items = this;
    for (var i = 0; i < items.length - 1; i++) {
        for (var j = 0; j < items.length - 1 - i; j++) {
            if (!isFirstGreaterThanSecond(items[j], items[j + 1])) {
                var temp = items[j + 1];
                items[j + 1] = items[j];
                items[j] = temp;
            }
        }
    }
    function isFirstGreaterThanSecond(first, second) {
        if (compare != undefined) {
            return compare(first, second);
        }
        else if (property == undefined || property == null) {
            return first > second;
        }
        else {
            return first[property] > second[property];
        }
    }
    return items;
};

Array.prototype.GroupBy = function (predicate) {
    var results = [];
    var items = this;

    var keys = {}, index = 0;
    for (var i = 0; i < items.length; i++) {
        var selector;
        if (typeof predicate === "string") {
            selector = items[i][predicate];
        } else {
            selector = predicate(items[i]);
        }
        if (keys[selector] === undefined) {
            keys[selector] = index++;
            results.push({ key: selector, value: [items[i]] });
        } else {
            results[keys[selector]].value.push(items[i]);
        }
    }
    return results;
};

Array.prototype.Each = function (func) {
    var items = this;
    for (var i = 0; i < items.length; i++) {
        func(items[i]);
    }
};